home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1999 March / EnigmA AMIGA RUN 35 (1999)(G.R. Edizioni)(IT)[!][issue 1999-03].iso / earcd / devel / libx11 / libx11 / alloca.c next >
C/C++ Source or Header  |  1999-01-01  |  2KB  |  111 lines

  1.  
  2. /****************************************************************************
  3.  *
  4.  *  alloca() implementation for SAS/C
  5.  *
  6.  *  Copyright: PUBLIC DOMAIN
  7.  *  Written by Stefan Proels <proels@fmi.uni-passau.de>
  8.  *
  9.  */
  10.  
  11. #include <stddef.h>
  12. #include <stdlib.h>
  13. #include <exec/types.h>
  14. #include <exec/memory.h>
  15. #include <clib/alib_protos.h>
  16. #include <constructor.h>
  17.  
  18.  
  19. #ifndef __SASC
  20. #error Wrong compiler (SAS/C required)
  21. #endif
  22.  
  23. #ifdef _PROFILE
  24. #error This file must NOT be compiled with PROFILE enabled
  25. #endif
  26.  
  27.  
  28. /*
  29.  * each alloca()ted block is preceded by this header
  30.  */
  31. struct block
  32.   {
  33.     struct block *down;
  34.     ULONG size;
  35.     ULONG level;
  36.     /* alloca()ted memory below */
  37.   };
  38.  
  39. static APTR pool = NULL;
  40. static struct block *top = NULL;
  41. ULONG __alloca_virtual_SP = 0;
  42.  
  43.  
  44. /*
  45.  * SAS/C autoinitialization function
  46.  */
  47. PROFILE_CONSTRUCTOR(Sprof)
  48. {
  49.   if (pool = LibCreatePool(MEMF_ANY, 4096, 2048))
  50.     return 0;
  51.   return -1;
  52. }
  53.  
  54. /*
  55.  * SAS/C autotermination function
  56.  */
  57. PROFILE_DESTRUCTOR(Sprof)
  58. {
  59.   if (pool)
  60.     LibDeletePool(pool);
  61. }
  62.  
  63.  
  64. /*
  65.  * called whenever a function is entered
  66.  */
  67. void __asm _PROLOG(register __a0 char *dummy)
  68. {
  69.   __alloca_virtual_SP++;
  70. }
  71.  
  72. /*
  73.  * called on return from a function
  74.  */
  75. void __asm _EPILOG(register __a0 char *dummy)
  76. {
  77.   struct block *mem;
  78.  
  79.   for (mem = top; mem && mem->level >= __alloca_virtual_SP; mem = top)
  80.     {
  81.       top = mem->down;
  82.       LibFreePooled(pool, mem, mem->size);
  83.     }
  84.   --__alloca_virtual_SP;
  85. }
  86.  
  87.  
  88. /*
  89.  * that's what the whole thing is all about -- alloca()te memory
  90.  */
  91. void *alloca(size_t size)
  92. {
  93.   struct block *mem;
  94.  
  95.   if (size <= 0)  /* garbage collection -- not required */
  96.     return NULL;
  97.  
  98.   size += sizeof(struct block);
  99.   if (!(mem = (struct block *)LibAllocPooled(pool, (ULONG)size)))
  100.     {
  101.       /* do whatever you want here */
  102.       abort();
  103.     }
  104.   mem->down = top;
  105.   mem->size = size;
  106.   mem->level = __alloca_virtual_SP;
  107.   top = mem;
  108.   return ++mem;
  109. }
  110.  
  111.